home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / CCDBMS.ZIP / DBARRAY.CPP < prev    next >
C/C++ Source or Header  |  1997-03-18  |  6KB  |  217 lines

  1. // =================================================================
  2. // Dbarray.cpp 
  3. // =================================================================
  4. // Harold Kasperink / John Dekker 
  5. // Dr. Dobb's Journal 1997
  6. // =================================================================
  7. // Multithreaded Database Array Singleton class
  8. // =================================================================
  9. #include <iostream.h>
  10. #include "dbarray.h"
  11.  
  12. // Fill singleton array with initial value
  13. CArrayDbase    *    CArrayDbase::g_pDbArray = 0;
  14. CMutex            CArrayDbase::g_mtxArray;
  15.  
  16. ////////////////////////////////////////////////////////////////////
  17. // CArrayDbase::CArrayDbase
  18. ////////////////////////////////////////////////////////////////////
  19. // Constructor
  20. ////////////////////////////////////////////////////////////////////
  21. CArrayDbase::CArrayDbase(int nNrConnections, const char *szUsr, const char *szPsswd, const char *szDB)
  22. {
  23.     m_nNrDbases = 0;
  24.     m_pszUsr = 0;
  25.     m_pszPsswd = 0;
  26.     m_pszDb = 0;
  27.     m_nCurCon = 0;
  28.     m_bPrint = FALSE;
  29.     memset(m_nDbUsage, 0, MAX_NR_DBASES*sizeof(int));
  30.     
  31.     // Check if database array object allready there
  32.     if (g_pDbArray != 0)
  33.         return;
  34.  
  35.     // Check parameter
  36.     if (nNrConnections < 1)
  37.         nNrConnections = 1;
  38.     if (nNrConnections > MAX_NR_DBASES)
  39.         nNrConnections = MAX_NR_DBASES;
  40.  
  41.     ConnectInfo(szUsr, szPsswd, szDB);
  42.  
  43.     // Create databases
  44.     for (int i=0; i<nNrConnections; i++) {
  45.         m_pDbases[i] = new CDbase;
  46.         if (m_pDbases[i] == 0) {
  47.             // Not succeedeed
  48.             cout << "No Connections\n";
  49.         }
  50.         m_nNrDbases = nNrConnections;
  51.     }
  52.  
  53.     // Create database threads
  54.     for (i=0; i<nNrConnections; i++) {
  55.         m_pDbases[i]->ConnectInfo(m_pszUsr, m_pszPsswd, m_pszDb);
  56.         m_pDbases[i]->Create();
  57.     }
  58.  
  59.     // Everything OK
  60.     g_pDbArray = this;
  61. }
  62.  
  63. ////////////////////////////////////////////////////////////////////
  64. // CArrayDbase::~CArrayDbase
  65. ////////////////////////////////////////////////////////////////////
  66. //    Destructor
  67. ////////////////////////////////////////////////////////////////////
  68. CArrayDbase::~CArrayDbase()
  69. {
  70.     DeleteConnectInfo();
  71.     m_bPrint = FALSE;
  72.  
  73.     if (this == g_pDbArray) {
  74.         Lock();
  75.         g_pDbArray = 0;
  76.         Unlock();
  77.     }
  78.  
  79.     for (int i=0; i<m_nNrDbases; i++) {
  80.         if (m_pDbases[i] != 0)
  81.             delete m_pDbases[i];
  82.     }
  83. }
  84.  
  85. ////////////////////////////////////////////////////////////////////
  86. // CArrayDbase::ConnectInfo
  87. ////////////////////////////////////////////////////////////////////
  88. // Set connect information strings
  89. ////////////////////////////////////////////////////////////////////
  90. void CArrayDbase::ConnectInfo(const char *szUsr, const char *szPsswd, const char *szDB)
  91. {
  92.     DeleteConnectInfo();
  93.  
  94.     if (szUsr != 0)
  95.         m_pszUsr = strdup(szUsr);
  96.     
  97.     if (szPsswd != 0)
  98.         m_pszPsswd = strdup(szPsswd);
  99.  
  100.     if (szDB != 0)
  101.         m_pszDb = strdup(szDB);
  102. }
  103.  
  104. ////////////////////////////////////////////////////////////////////
  105. // CArrayDbase::DeleteConnectInfo
  106. ////////////////////////////////////////////////////////////////////
  107. // free connect information strings
  108. ////////////////////////////////////////////////////////////////////
  109. void CArrayDbase::DeleteConnectInfo()
  110. {
  111.     if (m_pszUsr != 0)
  112.         delete m_pszUsr;
  113.     
  114.     if (m_pszPsswd != 0)
  115.         delete m_pszPsswd;
  116.     
  117.     if (m_pszDb != 0)
  118.         delete m_pszDb;
  119. }
  120.  
  121. ////////////////////////////////////////////////////////////////////
  122. // CArrayDbase::~ReserveDbase
  123. ////////////////////////////////////////////////////////////////////
  124. // Get free database connection from array object
  125. ////////////////////////////////////////////////////////////////////
  126. CDbase *CArrayDbase::ReserveDbase()
  127. {
  128.     // If no database array object
  129.     if (g_pDbArray == 0)
  130.         return 0;
  131.  
  132.     Lock();
  133.  
  134.     // Get dbases from database array object
  135.     CDbase **    pDbases = g_pDbArray->m_pDbases;
  136.     int            nNrDbases = g_pDbArray->m_nNrDbases;
  137.     int *        pCurCon = &g_pDbArray->m_nCurCon;
  138.     int *        nDbUsage = g_pDbArray->m_nDbUsage;
  139.     
  140.     // Loop for find a free database connection
  141.     while (TRUE) {
  142.         for (int i=0; i<nNrDbases; i++) {
  143.             // Database array object is delete in mean-time
  144.             if (g_pDbArray == 0)
  145.                 return 0;
  146.  
  147.             // Find free database
  148.             if (pDbases[i]->TryLock()) {
  149.                 nDbUsage[i] += 1;
  150.                 Unlock();
  151.                 return pDbases[i];
  152.             }
  153.         }
  154.  
  155.         // All connections are occupied, see take inuse one
  156.         CDbase *pDb = pDbases[*pCurCon];
  157.         nDbUsage[*pCurCon] += 1;
  158.         
  159.         // Increase next inuse counter
  160.         *pCurCon += 1;
  161.         if (*pCurCon >= nNrDbases)
  162.             *pCurCon = 0;
  163.  
  164.         Unlock();
  165.         pDb->Lock();
  166.         return pDb;
  167.     }
  168. }
  169.  
  170. ////////////////////////////////////////////////////////////////////
  171. // CArrayDbase::~ReleaseDbase
  172. ////////////////////////////////////////////////////////////////////
  173. // Release allocated database
  174. ////////////////////////////////////////////////////////////////////
  175. void CArrayDbase::ReleaseDbase(CDbase &dbase)
  176. {
  177.     // If no database array object
  178.     if (g_pDbArray == 0)
  179.         return;
  180.     
  181.     Lock();
  182.  
  183.     // Get dbases from database array object
  184.     CDbase **    pDbases = g_pDbArray->m_pDbases;
  185.     int            nNrDbases = g_pDbArray->m_nNrDbases;
  186.     int *        nDbUsage = g_pDbArray->m_nDbUsage;
  187.  
  188.     // Search for database
  189.     for (int i=0; i<nNrDbases; i++) {
  190.         // Find free database
  191.         if (pDbases[i] == &dbase) {
  192.             nDbUsage[i] -= 1;
  193.             dbase.Unlock();
  194.             Unlock();
  195.             return;
  196.         }
  197.     }
  198.     Unlock();
  199. }
  200.  
  201. ////////////////////////////////////////////////////////////////////
  202. // CArrayDbase::Lock
  203. ////////////////////////////////////////////////////////////////////
  204. void CArrayDbase::Lock()
  205. {
  206.     g_mtxArray.Lock();
  207. }
  208.  
  209. ////////////////////////////////////////////////////////////////////
  210. // CArrayDbase::UnLock
  211. ////////////////////////////////////////////////////////////////////
  212. void CArrayDbase::Unlock()
  213. {
  214.     g_mtxArray.Unlock();
  215. }
  216.  
  217.